home *** CD-ROM | disk | FTP | other *** search
- /* receive buffer allocation routines */
- /* used to provide buffers that can be gotten at interrupt time */
-
- #include "global.h"
- #include "mbuf.h"
- #include "buffers.h"
-
- #if (defined(MSDOS) && !defined(MSC))
- # include "alloc.h"
- #endif
-
- static unsigned max_rxbufs = 0; /* max number of rx bufs */
- static unsigned min_bufsize = MINRXBUFSIZ; /* min size of buffers */
- static unsigned max_bufsize = MAXRXBUFSIZ; /* max size of buffers */
-
- unsigned cur_rxbufs = 0; /* number of pre-allocated rx bufs */
- struct mbuf *sys_rxbufs = NULLBUF; /* list of pre-allocated buffers */
- struct mbuf *sys_txfree = NULLBUF; /* list of buffers freed by transmitter */
-
- /* "buffers" command sets the number of receive buffers */
-
- int
- dobuffers (argc,argv)
- int argc;
- char *argv[];
-
- {
- if (argc == 1)
- printf("%u buffers of %u .. %u bytes\n",max_rxbufs,
- min_bufsize,max_bufsize);
- else{
- max_rxbufs = atoi(argv[1]);
- if (argc > 2)
- min_bufsize = atoi(argv[2]);
- if (argc > 3)
- max_bufsize = atoi(argv[3]);
- if (min_bufsize < 2)
- min_bufsize = MINRXBUFSIZ;
- if (max_bufsize < min_bufsize)
- max_bufsize = min_bufsize;
- }
-
- buf_alloc(); /* alloc initial set of buffers */
- return 0;
- }
-
- /* check if enough buffers are on the receive buffer list
- * if not, allocate them and link to the list
- * also, buffers on the tx "to be freed" list are freed
- * malloc and free are only called with interrupts enabled,
- * because overruns will occur during the free list scan...
- */
- void
- buf_alloc()
- {
- register struct mbuf *bp;
- unsigned bufsize;
- int i_state;
- #if (defined(ATARI_ST) && defined(MWC))
- struct memblock { /* MW C freelist structure */
- long size;
- struct memblock *next;
- };
- extern struct memblock *_a_scanp; /* current start of scan */
- long blocksize;
- #endif
- #if (defined(MSDOS) && !defined(MSC))
- extern HEADER PTR allocp; /* current start of scan */
- unsigned blocksize;
- #endif
-
- while (sys_txfree != NULLBUF){ /* buffers to be freed */
- i_state = disable();
- bp = sys_txfree; /* unlink one buffer */
- sys_txfree = bp->next;
- restore(i_state);
-
- free(bp); /* free it with ints enabled */
- }
-
- while (cur_rxbufs < max_rxbufs){
- bufsize = max_bufsize; /* allocate maximum buffer */
-
- /* this piece of code tries to minimize the free list fragmentation
- * by taking a small block from the free list as a receive buffer.
- * any block between MIN and MAX bufsize will be allocated, resulting
- * in many exact fit allocations.
- */
-
- #if (defined(ATARI_ST) && defined(MWC))
- if (_a_scanp->size & 1) /* pointing to a free block? */
- {
- /* when free, check if next also free and join if so */
-
- while ((blocksize = ((struct memblock *) ((char *) _a_scanp + _a_scanp->size - 1))->size) & 1)
- {
- /* join next (free) block with this one */
- _a_scanp->size += blocksize - 1;
- }
-
- /* joined free blocks, now check if within limits */
- /* compute blocksize = sizeof(free block) - sizeof(struct mbuf) */
-
- blocksize = _a_scanp->size - 1 - sizeof(long) - sizeof(struct mbuf);
-
- if (blocksize >= min_bufsize && /* big enough? */
- blocksize <= max_bufsize) /* not too big? */
- {
- bufsize = (int) blocksize;
- }
- }
- #endif
- #if (defined(MSDOS) && !defined(MSC))
- /* compute blocksize = sizeof(free block) - sizeof(struct mbuf) */
-
- blocksize = allocp->s.size * sizeof(HEADER) - sizeof(HEADER) - sizeof(struct mbuf);
-
- if (blocksize >= min_bufsize && /* big enough? */
- blocksize <= max_bufsize) /* not too big? */
- {
- bufsize = blocksize;
- }
- #endif
-
- if ((bp = alloc_mbuf(bufsize)) == NULLBUF)
- break; /* no space, try again later */
-
- i_state = disable();
- bp->next = sys_rxbufs; /* link at head of chain */
- sys_rxbufs = bp;
- cur_rxbufs++;
- restore(i_state);
- }
- }
-
-